package com.itheima.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.dto.SetmealDto;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.Setmeal;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.service.DishService;
import com.itheima.reggie.service.SetmealDishService;
import com.itheima.reggie.service.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 套餐管理
 */
@RestController
@RequestMapping("/setmeal")
@Slf4j
public class SetmealController {
    @Autowired
    private SetmealService setmealService;
    @Autowired
    private SetmealDishService setmealDishService;
    @Autowired
    private DishService dishService;

    // 增
    //F. 保存套餐信息  请求方式POST   请求路径/setmeal  请求参数 json格式数据
    //  SetmealController中定义方法save，新增套餐
    //在该Controller的方法中,我们不仅需要保存套餐的基本信息，还需要保存套餐关联的菜品数据，所以我们需要再该方法中调用业务层方法,完成两块数据的保存。
    //页面传递的数据是json格式，需要在方法形参前面加上@RequestBody注解, 完成参数封装。
    @PostMapping
    @CacheEvict(cacheNames = "setmeal",key = "#setmealDto.categoryId+'_'+1")
    public R save(@RequestBody SetmealDto setmealDto) {
        log.info("要添加的是:{}", setmealDto);
        setmealService.saveWithDish(setmealDto);
        return R.success("添加成功");
    }


    // 删
    @DeleteMapping
    @CacheEvict(cacheNames = "setmeal",allEntries = true)
    public R<String> delete(@RequestParam List<Long> ids) {
        log.info("ids:{}", ids);
        setmealService.deleteByIds(ids);
        return R.success("套餐数据删除成功");
    }

    // 查,根据id查回显数据,改之前应该先回显数据
    //  get请求,id是路径参数
    @GetMapping("/{id}")
    @Cacheable(cacheNames = "setmeal",key = "#id")
    public R getById(@PathVariable Long id) {
        Setmeal setmeal = setmealService.getById(id);
        SetmealDto dto = new SetmealDto();
        BeanUtils.copyProperties(setmeal, dto);
        // 需要菜品集
        LambdaQueryWrapper<SetmealDish> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SetmealDish::getSetmealId, id);
        List<SetmealDish> list = setmealDishService.list(lqw);
        dto.setSetmealDishes(list);
        return R.success(dto);
    }

    // 改 改dto  post请求 需要对套餐菜品关系表操作,去service
    @PutMapping
    @CacheEvict(cacheNames = "setmeal",allEntries = true)
    public R update(@RequestBody SetmealDto setmealDto) {
        log.info("要修改的是{}", setmealDto);
        setmealService.updateWithDish(setmealDto);
        return R.success("修改成功");
    }

    // 改状态
    @PostMapping("/status/{type}")
    @CacheEvict(cacheNames = "setmeal",allEntries = true)
    public R updateStatus(@PathVariable Integer type, Long[] ids) {
        log.info("要修改的有{}", ids);
        setmealService.updateStatus(type, ids);

        return R.success("修改成功");
    }

    // 查 分页查询
    @GetMapping("/page")
    @Cacheable(cacheNames = "setmeal",key = "#page + '_' + #pageSize + '_' + #name")
    public R page(Integer page, Integer pageSize, String name) {
        // 简单一点,整个xml
        IPage<SetmealDto> pageInfo = setmealService.pageWithDish(page, pageSize, name);
        return R.success(pageInfo);
    }

    // 查  get  /list?categoryId=1397844263642378242&status=1
    @GetMapping("/list")
    @Cacheable(cacheNames = "setmeal",key = "#setmeal.categoryId + '_' + 1")
    public R list(Setmeal setmeal) {
        LambdaQueryWrapper<Setmeal> sdLqw = new LambdaQueryWrapper<>();
        sdLqw.eq(setmeal.getCategoryId() != null, Setmeal::getCategoryId, setmeal.getCategoryId());
        sdLqw.eq(setmeal.getStatus() != null, Setmeal::getStatus, 1);
        sdLqw.orderByDesc(Setmeal::getUpdateTime);
        List<Setmeal> list = setmealService.list(sdLqw);
        return R.success(list);
    }

    @GetMapping("/dish/{id}")
    @Cacheable(cacheNames = "setmeal",key = "#id ")
    public R getDishsById(@PathVariable Long id) {
        LambdaQueryWrapper<SetmealDish> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SetmealDish::getSetmealId, id);
        List<SetmealDish> list = setmealDishService.list(lqw);
        Set<Long> idSet = list.stream().map(setmealDish -> {
            Long dishId = setmealDish.getDishId();
            return dishId;
        }).collect(Collectors.toSet());
        List<Dish> dishes = dishService.listByIds(idSet);
        List<DishDto> dtoList = dishes.stream().map(dish -> {
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(dish, dishDto);
            return dishDto;
        }).collect(Collectors.toList());
        dtoList.forEach(DishDto->{
            Long dtoId = DishDto.getId();
            for (SetmealDish setmealDish : list) {
                if (dtoId.equals(setmealDish.getDishId())) {
                    DishDto.setCopies(setmealDish.getCopies());
                }
            }
        });


        return R.success(dtoList);

    }

}